使用STM32的GPIO模拟I2C通信:从原理到实现 |
您所在的位置:网站首页 › stm32 i2c从设备 › 使用STM32的GPIO模拟I2C通信:从原理到实现 |
#include "stm32f4xx_hal.h" // GPIO定义#define SDA_GPIO_PORT GPIOA#define SDA_PIN GPIO_PIN_0 #define SCL_GPIO_PORT GPIOA#define SCL_PIN GPIO_PIN_1 // 模拟I2C句柄定义typedef struct { GPIO_TypeDef *SDA_GPIO_Port; uint16_t SDA_Pin; GPIO_TypeDef *SCL_GPIO_Port; uint16_t SCL_Pin;} SimulatedI2C_HandleTypeDef; // 函数声明void SimulatedI2C_Init(SimulatedI2C_HandleTypeDef *hi2c);void SimulatedI2C_Write(SimulatedI2C_HandleTypeDef *hi2c, uint8_t dev_addr, uint8_t *data, uint16_t size);void SimulatedI2C_Read(SimulatedI2C_HandleTypeDef *hi2c, uint8_t dev_addr, uint8_t *data, uint16_t size); // 延迟函数void I2C_Delay(void) { // 根据需要添加延迟,也可以用HAL库的HAL_Delay(); for (int i = 0; i < 100; i++);} // 启动条件void I2C_Start(SimulatedI2C_HandleTypeDef *hi2c) { HAL_GPIO_WritePin(hi2c->SDA_GPIO_Port, hi2c->SDA_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(hi2c->SCL_GPIO_Port, hi2c->SCL_Pin, GPIO_PIN_SET); I2C_Delay(); HAL_GPIO_WritePin(hi2c->SDA_GPIO_Port, hi2c->SDA_Pin, GPIO_PIN_RESET); I2C_Delay(); HAL_GPIO_WritePin(hi2c->SCL_GPIO_Port, hi2c->SCL_Pin, GPIO_PIN_RESET); I2C_Delay();} // 停止条件void I2C_Stop(SimulatedI2C_HandleTypeDef *hi2c) { HAL_GPIO_WritePin(hi2c->SDA_GPIO_Port, hi2c->SDA_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(hi2c->SCL_GPIO_Port, hi2c->SCL_Pin, GPIO_PIN_SET); I2C_Delay(); HAL_GPIO_WritePin(hi2c->SDA_GPIO_Port, hi2c->SDA_Pin, GPIO_PIN_SET); I2C_Delay();} // 写入单个字节void I2C_WriteByte(SimulatedI2C_HandleTypeDef *hi2c, uint8_t byte) { for (int8_t i = 7; i >= 0; i--) { if (byte & (1 SDA_GPIO_Port, hi2c->SDA_Pin, GPIO_PIN_SET); } else { HAL_GPIO_WritePin(hi2c->SDA_GPIO_Port, hi2c->SDA_Pin, GPIO_PIN_RESET); } I2C_Delay(); HAL_GPIO_WritePin(hi2c->SCL_GPIO_Port, hi2c->SCL_Pin, GPIO_PIN_SET); I2C_Delay(); HAL_GPIO_WritePin(hi2c->SCL_GPIO_Port, hi2c->SCL_Pin, GPIO_PIN_RESET); I2C_Delay(); }} // 读取单个字节uint8_t I2C_ReadByte(SimulatedI2C_HandleTypeDef *hi2c) { uint8_t byte = 0; for (int8_t i = 7; i >= 0; i--) { HAL_GPIO_WritePin(hi2c->SCL_GPIO_Port, hi2c->SCL_Pin, GPIO_PIN_SET); I2C_Delay(); if (HAL_GPIO_ReadPin(hi2c->SDA_GPIO_Port, hi2c->SDA_Pin)) { byte |= (1 SCL_GPIO_Port, hi2c->SCL_Pin, GPIO_PIN_RESET); I2C_Delay(); } return byte;} // 模拟I2C初始化void SimulatedI2C_Init(SimulatedI2C_HandleTypeDef *hi2c) { GPIO_InitTypeDef GPIO_InitStruct = {0}; // 初始化SDA引脚 GPIO_InitStruct.Pin = hi2c->SDA_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(hi2c->SDA_GPIO_Port, &GPIO_InitStruct); // 初始化SCL引脚 GPIO_InitStruct.Pin = hi2c->SCL_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(hi2c->SCL_GPIO_Port, &GPIO_InitStruct);} // 向设备写入数据void SimulatedI2C_Write(SimulatedI2C_HandleTypeDef *hi2c, uint8_t dev_addr, uint8_t *data, uint16_t size) { // 发送起始条件 I2C_Start(hi2c); // 发送设备地址和写入位 I2C_WriteByte(hi2c, dev_addr |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |